import java.io.*;
import java.util.*;
/**
 * The lookup component of the search engine: takes in the search keywords, and 
 * finds the associated URLs and returns them in ascending order according to their
 * relative weights
 * @author alrik firl (afirl)
 * @author Pin-Wei Cheng (picheng)
 */
public class Lookup {
	Hashtable<String, Hashtable<String, Integer>> inputTable;
	
	/**
	 * Reads in the user-queries from the command line and drives the rest of the program 
	 * @param args denotes the file name to read from Index.java
	 */
	public static void main(String [] args){
		Scanner in = new Scanner(System.in);
		Lookup caller = new Lookup();
		try{
			caller.ReadFile(args[0]);
		}catch(Exception e){
			System.out.println("Specify the input file");
		}
		while(true){
			System.out.println("Enter keyword query (blank line to exit the program): ");
			String search_term = in.nextLine();
			
			if(search_term.equals("")){
				System.out.println("Goodbye");
				System.exit(0);
			}
				
			
			caller.findAndOut(search_term);
		}
	}
	/**
	 * Searches for the input parameter keyword in the hashtable of keywords and their
	 * associated URL and its weighting; if it finds the keyword, then it'll print out
	 * it's corresponding URLs and their weightings in sequential order.
	 * @param intoken the keyword to lookup in the hashtable of indexed values
	 * @return denotes whether the keyword was found or not
	 */
	@SuppressWarnings("unchecked")
	private boolean findAndOut(String intoken){
		Hashtable<String, Integer> printpriority = new Hashtable<String, Integer>();
		Vector<String> containList = new Vector<String>();
		Vector<String> strikeList = new Vector<String>();
		boolean found = false;
		String[] string = new String(intoken).split("\\W");
		int count = 0;
		
		/*loop through all the query keywords*/
		for (String token : string) {
			String lookup = Keyword.makeKeyword(token);
			/*gets the sub-hashtable corresponding to the value of lookup key*/
			Hashtable<String, Integer> values = inputTable.get(lookup);
			/*If the keyword was present in any of the visited URLs*/ 
			if (lookup.equals("")) {
				System.out.println("'" + token + "'" + " stems to --> " + "'"
						+ lookup + "'" + " ignoring");
				continue;
			}
			if (!(values == null)) {
				System.out.println("'" + token + "'" + " stems to --> " + "'"
						+ lookup + "':" + " found in " + values.size()
						+ " web pages.");

				/*All the URLs that contain the keyword*/
				Set<String> printTable = values.keySet();
				/*accumulate all the URL's and their collective weights*/
				for(String a:printTable){
					int weight = values.get(a);
					//token is String --> key, value is Integer --> weight
					if(printpriority.containsKey(a)){
						if(count == 0){
							containList.add(a);
						}else{
							for(String prev:containList){
								if(!printTable.contains(prev)){
									strikeList.add(prev);
								}
							}
						}
						Integer tmpURL = printpriority.get(a);
						printpriority.remove(a);
						int update = tmpURL+weight;
						printpriority.put(a, update);
					}else{
						printpriority.put(a, weight);
						if(count == 0){
							containList.add(a);
						}else{
							strikeList.add(a);
						}
					}
				}
				count++;
			/*if the keyword wasn't present in any of the parsed webpages*/
			} else {
				System.out.println("No Valid Keywords! Try again.");
				return found;
			}
		}
		
		/*sorts the results of the keyword query*/
		Object sortArr[] = new Integer[printpriority.size()];
		sortArr = printpriority.entrySet().toArray();
		comp compareator = new comp();
		Arrays.sort(sortArr, (Comparator) compareator);
		/*removes the web pages that dont contain all query terms*/
		Vector<String> print = new Vector<String>();
		Hashtable<String, Object> printHashtable = new Hashtable<String, Object>();
		for (int i = 0; i < sortArr.length; i++) {
			if(!strikeList.contains((String)((Map.Entry) sortArr[i]).getKey())){
				print.add((String)((Map.Entry) sortArr[i]).getKey());
				printHashtable.put((String)((Map.Entry) sortArr[i]).getKey(), 
						((Map.Entry) sortArr[i]).getValue());
			}
		}

		/*prints the sorted keyword query result*/
		System.out.println("RESULTS: " + print.size() + " documents match all query keywords.");
		System.out.println("Here they are, in sorted order: ");
		for (int i = 0; i < printHashtable.size(); i++) {
			//System.out.println(printHashtable.elementAt(i)+": score "+(((Map.Entry) sortArr[i]).getValue()));
			System.out.print(print.elementAt(i)+": score ");
			System.out.println(printHashtable.get(print.elementAt(i)));
		}
		return true;
	}
	
	/**
				print.put
	 * Reads the file written by Index.java; from the file it reads in the hashtable of indexed 
	 * keywords and their URLs and weights. 
	 * @param filenm the file read by the program to get the table of values from Index.java
	 */
	@SuppressWarnings("unchecked")
	private void ReadFile(String filenm){
		System.out.print("Reading index file "+ filenm+"... ");
		File file = new File(filenm);
		try{
			InputStream filein = new FileInputStream(file);
			InputStream bufferin = new BufferedInputStream(filein);
			ObjectInput input = new ObjectInputStream(bufferin);
		    inputTable = (Hashtable<String, Hashtable<String, Integer>>) input.readObject();
		    System.out.println("Contains "+ inputTable.size()+ " keywords");
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("no file was obtained, exiting ");
			System.exit(1);
			
		}
	}
}

